/**
 *  jQuery.jsonengine
 */
(function($) {
	$.jsonengine = function() {	};
	$.jsonengine.version = '02-28-2011';
})(jQuery);

/**
 *  jQuery.jsonengine.utils
 */
(function($) {
	$.jsonengine.utils = function() { };
	/**
	 * jsonデータをhtmlリスト形式へ
	 */
	$.jsonengine.utils.json2htmlList = function(json, header) {
		var h = '';
		if(header) h = header;
		if (!json) {
			return json;
		} else if (Object.prototype.toString.call(json)=='[object Object]') {
			var dl = $('<dl class="' + h + 'object_Object">');
			for ( var key in json) {
				dl.append($('<dt class="' + h + key + '">').html(key));
				dl.append($('<dd class="' + h + 'value-' + key + '">').html($.jsonengine.utils.json2htmlList(json[key])));
			}
			return dl;
		} else if (Object.prototype.toString.call(json)=='[object Array]') {
			var ol = $('<ol class="' + h + 'object_Array">');
			var json_length = json.length;
			for ( var i = 0; i < json_length; i++) {
				ol.append($('<li class="' + h + 'value">').html($.jsonengine.utils.json2htmlList(json[i])));
			}
			return ol;
		} else {
			return json;
		}
	};
	/**
	 *  TODO htmlリストをjsonデータ形式へ
	 */
	$.jsonengine.utils.htmlList2json = function(html, header) {
		var h = '';
		if(header) h = header;
		if (!html) {
			return html;
		} else {
			return html;
		}
	};
	/**
	 *  example: valueFromHtmlList( $($.jsonengine.utils.json2htmlList(json)).find('.key').get(0) );
	 */
	$.jsonengine.utils.valueFromHtmlList = function(key){
		if(!key) return key;
		var nextNode = function(node) {
			var n;
			if (n = node.firstChild) return n;
			do if (n = node.nextSibling) return n; while (node = node.parentNode);
			return null;
		};
		var e = nextNode(nextNode(key)).firstChild;
		if(!e) return e;
		if(Object.prototype.toString.call(e)==='[object Text]'){
			return e.nodeValue;
		} else {
			return e;
		}
	};
})(jQuery);

/**
 *  jQuery.fn.jsonengine
 */
(function($) {
	$.jsonengine.fn = function() { };
	// jsonengineからデータ読み込み成功した際のコールバック関数
	$.jsonengine.fn.success = function(o, response, status) {
		var tmp = o.find('span.query');
		o.empty();
		o.append(tmp);
		delete tmp;
		// htmlリストを追加
		var e = $.jsonengine.utils.json2htmlList(response);
		if(e.html()!==''){
			o.append($('<div class="success">').append(e));
		}
	};
	// jsonengineからデータ読み込み失敗した際のコールバック関数
	$.jsonengine.fn.error = function(o, xhr, status, thrown){
		o.append($('<div class="error">')
			.append('status:')
				.append($('<span style="color:red;font-weight:bold;">')
					.append(status)));
	};
	// $.ajax(option)のラッパー(o, xhr, status, thrown)
	$.jsonengine.fn.ajax = function(option) {
		$.ajax(option);
	};
	// プラグインの定義
	$.fn.extend( {
		// htmlに記述された情報からURL文字列を構築する
		_URL : function() {
			var docType = this
				.attr('class')
				.match(/_je_.*?\b/)[0]
				.replace('_je_','_je/');
			var query = this
				.find('span.query').eq(0)
				.text()
				.trim();
			return '/' + docType + query;
		},
		// jsonengineから取得したデータを要素内に追加するプラグイン
		_LOAD : function(success, error) {
			url = this._URL();
			// コールバック関数へ引数を渡すための関数 成功用
			var callback_success = function(o, func) {
				return function(response, status) {
					func(o, response, status);
				};
			};
			// コールバック関数へ引数を渡すための関数 失敗用
			var callback_error = function(o, func) {
				return function(xhr, status, thrown) {
					func(o, xhr, status, thrown);
				};
			};
			// jsonengineからデータ読み込み成功した際のコールバック関数
			var _success = $.jsonengine.fn.success;
			// jsonengineからデータ読み込み失敗した際のコールバック関数
			var _error = $.jsonengine.fn.error;
			// 引数にsuccessがある場合
			if (success) _success = success;
			// 引数にerrorがある場合
			if (error) _error = error;
			// $.ajax()用引数の構築
			var option = {
				"type"    : "GET",
				"url"     : url,
				"data"    : "",
				"success" : callback_success(this, _success),
				"error"   : callback_error(this, _error)
			};
			// $.ajax()を実行する
			$.jsonengine.fn.ajax(option);
		}
	});
})(jQuery);

/**
 *  ready
 */
$(function() {
	// htmlに定義されたクラス名 '_je_*'を解釈して
	var docTypeElements = $('*[class*=_je_]');
	// jsonengineからデータを取得、表示する。
	for ( var i = 0; i < docTypeElements.length; i++) {
		docTypeElements.eq(i)._LOAD();
	}
});



